/*
 * Copyright (C) 2023 Coder.AN
 * Email: an.hongjun@foxmail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#include "xbox_filter.h"


int map(int x, int in_min, int in_max, int out_min, int out_max)
{
    return (int)(((double)x - (double)in_min) * ((double)out_max - (double)out_min) / ((double)in_max - (double)in_min) + (double)out_min);
}

void xbox_filter(struct XBoxInputVal &val)
{
    int X1 = val.X1;
    int Y1 = val.Y1;
    int X2 = val.X2;
    int Y2 = val.Y2;
    int lt = val.lt;
    int rt = val.rt;
    
    // 死区
    if (abs(X1) < DIE_X1) X1 = 0;
    else X1 = X1 < 0 ? X1 + DIE_X1 : X1 - DIE_X1;
    if (abs(Y1) < DIE_Y1) Y1 = 0;
    else Y1 = Y1 < 0 ? Y1 + DIE_Y1 : Y1 - DIE_Y1;
    if (abs(X2) < DIE_X2) X2 = 0;
    else X2 = X2 < 0 ? X2 + DIE_X2 : X2 - DIE_X2;
    if (abs(Y2) < DIE_Y2) Y2 = 0;
    else Y2 = Y2 < 0 ? Y2 + DIE_Y2 : Y2 - DIE_Y2;
    
    // 最大值限幅
    if (X1 > MAX_X1) X1 = MAX_X1;
    if (Y1 > MAX_Y1) Y1 = MAX_Y1;
    if (X2 > MAX_X2) X2 = MAX_X2;
    if (Y2 > MAX_Y2) Y2 = MAX_Y2;
    
    // 最小值限幅
    if (X1 < MIN_X1) X1 = MIN_X1;
    if (Y1 < MIN_Y1) Y1 = MIN_Y1;
    if (X2 < MIN_X2) X2 = MIN_X2;
    if (Y2 < MIN_Y2) Y2 = MIN_Y2;
    
    // 归一化
    X1 = map(X1, MIN_X1, MAX_X1, STD_MIN_X1, STD_MAX_X1);
    Y1 = map(Y1, MIN_Y1, MAX_Y1, STD_MIN_Y1, STD_MAX_Y1);
    X2 = map(X2, MIN_X2, MAX_X2, STD_MIN_X2, STD_MAX_X2);
    Y2 = map(Y2, MIN_Y2, MAX_Y2, STD_MIN_Y2, STD_MAX_Y2);
    lt = map(lt, 0     , 1023  , STD_MIN_LT, STD_MAX_LT);
    rt = map(rt, 0     , 1023  , STD_MIN_RT, STD_MAX_RT);

    val.X1 = X1;
    val.Y1 = Y1;
    val.X2 = X2;
    val.Y2 = Y2;
    val.lt = lt;
    val.rt = rt;
}